package org.lex.lang;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class ClassUtils {
	public static URLClassLoader loadJar(File... jars) {
		return loadJar(Thread.currentThread().getContextClassLoader(), jars);
	}

	public static URLClassLoader loadJar(ClassLoader parent, File... jars) {
		URL[] urls = new URL[jars.length];
		for (int i = 0, n = jars.length; i < n; i++) {
			try {
				urls[i] = jars[i].toURI().toURL();
			} catch (MalformedURLException cannotHappen) {
				cannotHappen.printStackTrace();
			}
		}
		return URLClassLoader.newInstance(urls, parent);
	}

	/**
	 * Load all class names from a jar file.<br>
	 * Note: innter class name are ignored
	 * 
	 * @param jar
	 * @return
	 * @throws IOException
	 */
	public static Collection<String> getClassNames(File jar) throws IOException {
		JarFile file = new JarFile(jar);
		Enumeration<JarEntry> entries = file.entries();
		Collection<String> set = new LinkedList<String>();
		while (entries.hasMoreElements()) {
			JarEntry e = entries.nextElement();
			if (false == e.isDirectory()) {
				String name = e.getName();
				String className = getClassName(name);
				if (null != className) {
					set.add(className);
				}
			}
		}
		return set;
	}

	/**
	 * Load all class names from a directory, which contains .class files. <br>
	 * Note: innter class name are ignored.
	 * 
	 * @param dir
	 * @return
	 */
	public Collection<String> getClassNamesFromDirectory(File dir) {
		return null;
	}

	private static String getClassName(String path) {
		String className = null;
		if (-1 == path.indexOf('$')) {
			int dotIndex = path.lastIndexOf('.');
			if (-1 != dotIndex && dotIndex < path.length() - 1) {
				String suffix = path.substring(dotIndex + 1);
				if (suffix.toLowerCase().equals("class")) {
					className = path.substring(0, dotIndex);
					className = className.replace('/', '.');
				}
			}
		}
		return className;
	}
}
